﻿/* 2014/1/11 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Cosmos.Collections
{
    /// <summary>
    /// Represents a collection can switch between queue and stack.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class SwitchableCollection<T>
    {
        LinkedList<T> _list;

        public SwitchableCollection()
        {
            _list = new LinkedList<T>();
        }

        public void Store(T item)
        {
            switch (Mode)
            {
                case SwitchableCollectionMode.List:
                    throw new InvalidOperationException();

                case SwitchableCollectionMode.Queue:
                    _list.AddFirst(item);
                    break;

                case SwitchableCollectionMode.Stack:
                    _list.AddFirst(item);
                    break;

                default:
                    break;
            }
        }

        public T Take()
        {
            T item = default(T);
            switch (Mode)
            {
                case SwitchableCollectionMode.List:
                    throw new InvalidOperationException();

                case SwitchableCollectionMode.Queue:
                    if (_list.Count > 0)
                    {
                        item = _list.Last.Value;
                        _list.RemoveLast();
                    }
                    else
                    {
                        throw new InvalidOperationException();
                    }
                    break;
                    
                case SwitchableCollectionMode.Stack:
                    if (_list.Count > 0)
                    {
                        item = _list.First.Value;
                        _list.RemoveFirst();
                    }
                    else
                    {
                        throw new InvalidOperationException();
                    }
                    break;

                default:
                    break;
            }
            return item;
        }

        public void Clear()
        {
            _list.Clear();
        }

        public int Count
        {
            get 
            {
                return _list.Count;
            }
        }

        public SwitchableCollectionMode Mode
        {
            get;
            set;
        }
    }
}
